<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of MtUpload
 *
 * @author Administrator
 */
Yii::import('application.library.upload.UploadFile');

class MtUpload {

    //put your code here
    protected $bhv;  // 上传行为配置
    protected $store; // 附件存储器

    public function __construct(BaseUploadAction $bhv) {
        $this->bhv = $bhv;
        $this->setStore();
    }

    public function getBehavior() {
        return $this->bhv;
    }

    /**
     * 设置附件存储对象
     */
    public function setStore() {
        $store = $this->bhv->isLocal ? 'StorageLocal' : 'StorageYun';
        Yii::import('application.library.storage.' . $store);
        $this->store = new $store;

        // $this->store = Wind::getComponent($this->bhv->isLocal ? 'localStorage' : 'storage');
    }

    /**
     * 检查是否可以上传
     *
     * @return bool|PwError
     */
    public function check() {
        return $this->bhv->check();
    }

    /**
     * 获取已上传附件个数
     *
     * @return int
     */
    public function getUploadNum() {
        return $this->bhv->getUploadNum();
    }

    /**
     * 过滤文件名
     *
     * @param string $filename
     * @return string
     */
    public function filterFileName($filename) {
        return preg_replace('/\.(php|asp|jsp|cgi|fcgi|exe|pl|phtml|dll|asa|com|scr|inf)$/i', ".scp_\\1", $filename);
    }

    /**
     * 保存文件
     *
     * @param PwUploadFile $file
     * @return bool|PwError
     */
    public function saveFile($file) {
        if (($result = $this->store->save($file->source, $file->fileuploadurl)) !== true) {
            return $result;
        }
        if ($thumb = $file->getThumb()) {
            foreach ($thumb as $key => $value) {
                $this->store->save($value[0], $value[1]);
            }
        }
        return true;
    }

    /**
     * 上传附件主流程
     *
     * @return mixed
     */
    public function execute() {
        $uploaddb = array();
        foreach ($_FILES as $key => $value) {

            if (!self::isUploadedFile($value['tmp_name']) || !$this->bhv->allowType($key)) {
                continue;
            }

            $file = new UploadFile($key, $value);

            if (($result = $this->checkFile($file)) !== true) {
                return $result;
            }

            $file->filename = $this->filterFileName($this->bhv->getSaveName($file));
            $file->savedir = $this->bhv->getSaveDir($file);
            $file->source = $this->store->getAbsolutePath($file->filename, $file->savedir);

            if (!self::moveUploadedFile($value['tmp_name'], $file->source)) {
                return new BaseError(BaseError::E_CREATEDIR_FAIURE);
            }
            //处理文件
            if (($result = $file->operate($this->bhv, $this->store)) !== true) {
                $this->bhv->fileError($file);
                return $result;
            }
            if (($result = $this->saveFile($file)) !== true) {
                return $result;
            }
            $uploaddb[] = $file->getInfo();
        }
        return $this->bhv->update($uploaddb);
    }
    
    public function executeMultiple($key){
    	$uploaddb = array();
	    	
    	if(is_array($_FILES[$key])){
    		$up_arr = count($_FILES[$key]);
    		$up_all = count($_FILES[$key], 1);
    		$up_cnt = ($up_all - $up_arr) / $up_arr;
	    	
	    	for ($i = 0; $i < $up_cnt; $i ++) {
	    		if ($_FILES[$key]['error'][$i] != 4) {
	    			$up_files[] = array(
	    					'tmp_name' => $_FILES[$key]['tmp_name'][$i],
	    					'name' => $_FILES[$key]['name'][$i],
	    					'type' => $_FILES[$key]['type'][$i],
	    					'size' => $_FILES[$key]['size'][$i],
	    					'error' => $_FILES[$key]['error'][$i]
	    			);
	    		}
	    	}
	    	
	    	if(isset($up_files) && is_array($up_files)){
	    		foreach ($up_files as $k => $value){
	    			
	    				if (!self::isUploadedFile($value['tmp_name']) || !$this->bhv->allowType($key)) {
	    					continue;
	    				}
	    			
	    				$file = new UploadFile($key, $value);
	    			
	    				if (($result = $this->checkFile($file)) !== true) {
	    					return $result;
	    				}
	    			
	    				$file->filename = $this->filterFileName($this->bhv->getSaveName($file));
	    				$file->savedir = $this->bhv->getSaveDir($file);
	    				$file->source = $this->store->getAbsolutePath($file->filename, $file->savedir);
	    			
	    				if (!self::moveUploadedFile($value['tmp_name'], $file->source)) {
	    					return new BaseError(BaseError::E_CREATEDIR_FAIURE);
	    				}
	    				//处理文件
	    				if (($result = $file->operate($this->bhv, $this->store)) !== true) {
	    					$this->bhv->fileError($file);
	    					return $result;
	    				}
	    				if (($result = $this->saveFile($file)) !== true) {
	    					return $result;
	    				}
	    				$uploaddb[] = $file->getInfo();
	    			
	    		}
	    	}
    	}
    	return $this->bhv->update($uploaddb);
    }
    /**
     * 上传单个文件
     * 
     */
    public function executeSingle($key,$upfile) {
    	$uploaddb = array();
    	

    		if (!self::isUploadedFile($upfile['tmp_name']) || !$this->bhv->allowType($key)) {
    			return false;
    		}
    	
    		$file = new UploadFile($key, $upfile);
    	
    		if (($result = $this->checkFile($file)) !== true) {
    			return $result;
    		}
    	
    		$file->filename = $this->filterFileName($this->bhv->getSaveName($file));
    		$file->savedir = $this->bhv->getSaveDir($file);
    		$file->source = $this->store->getAbsolutePath($file->filename, $file->savedir);
    	
    		if (!self::moveUploadedFile($upfile['tmp_name'], $file->source)) {
    			return new BaseError(BaseError::E_CREATEDIR_FAIURE);
    		}
    		//处理文件
    		if (($result = $file->operate($this->bhv, $this->store)) !== true) {
    			$this->bhv->fileError($file);
    			return $result;
    		}
    		if (($result = $this->saveFile($file)) !== true) {
    			return $result;
    		}
    		$uploaddb[] = $file->getInfo();
    		
    	
    	return $this->bhv->update($uploaddb);
    }

    /**
     * 移动上传文件
     *
     * @param string $tmp_name 源文件
     * @param string $filename 移动后的文件地址
     * @return bool
     */
    public static function moveUploadedFile($tmp_name, $filename) {
        if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match("/\.php$/i", $filename)) {
            exit('illegal file type!');
        }
        self::createFolder(dirname($filename));
        if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) {
            @chmod($filename, 0777);
            return true;
        }
        if (self::copyFile($tmp_name, $filename)) {
            return true;
        }
        return false;
    }

    /**
     * 创建目录
     *
     * @param string $path
     */
    public static function createFolder($path) {
        if (!is_dir($path)) {
            self::createFolder(dirname($path));
            @mkdir($path);
            @chmod($path, 0777);
            @fclose(@fopen($path . '/index.html', 'w'));
            @chmod($path . '/index.html', 0777);
        }
    }

    /**
     * 检查上传文件是否符合规定
     *
     * @param PwUploadFile $file
     * @return bool|PwError
     */
    public function checkFile($file) {
        if (!$file->ext || !isset($this->bhv->ftype[$file->ext])) {
            return new BaseError(BaseError::E_FILE_EXT_ERROR);
        }
        if ($file->size < 1) {
            return new BaseError(BaseError::E_FILE_SIZE_ERROR);
        }
        if ($file->size > $this->bhv->ftype[$file->ext] * 1024) {
             return new BaseError(BaseError::E_FILE_SIZE_ERROR);
        }
        return true;
    }

    /**
     * 判断是否是正常的上传文件
     *
     * @param string $tmp_name
     * @return bool
     */
    public static function isUploadedFile($tmp_name) {
        if (!$tmp_name || $tmp_name == 'none') {
            return false;
        } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) {
            return false;
        } else {
            return true;
        }
    }

}
